/*
 * Copyright (c) 2019 The sky Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.qinker.robot.hook;

import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
import android.text.TextUtils;

import com.qinker.robot.hook.aio.ClientStart;
import com.qinker.robot.hook.aio.senter.RobotSenter;
import com.qinker.robot.hook.data.M;
import com.qinker.robot.hook.data.VersionManager;
import com.qinker.robot.hook.plugin.PluginManager;
import com.qinker.robot.hook.plugin.interfaces.XConfig;
import com.qinker.robot.hook.plugin.interfaces.XPluginManager;
import com.qinker.robot.hook.plugin.interfaces.XVersionManager;
import com.qinker.robot.hook.schedule.RobotHeartbeat;
import com.qinker.robot.hook.util.DingHookUtils;
import com.sky.xposed.common.util.Alog;
import com.sky.xposed.javax.MethodHook;
import com.sky.xposed.javax.XposedPlus;
import com.sky.xposed.javax.XposedUtil;

import org.apache.commons.lang3.StringUtils;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

/**
 * Created by sky on 2019/3/14.
 */
public class Main implements IXposedHookLoadPackage, MethodHook.ThrowableCallback {


    @Override
    public void onThrowable(Throwable tr) {
        Alog.e("Throwable", tr);
    }

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpParam) throws Throwable {


        Alog.setDebug(BuildConfig.DEBUG);
        if (!StringUtils.equals(Constant.Rimet.PACKAGE_NAME, lpParam.packageName)
                || !StringUtils.equals(Constant.Rimet.PACKAGE_NAME, lpParam.processName)) {
            return;
        }


        // 获取版本管理对象
        XVersionManager versionManager = new VersionManager
                .Build(ActivityThread.currentActivityThread().getSystemContext())
                .build();

        Alog.i("插件注入成功..." + versionManager.getVersionName());
        if (!versionManager.isSupportVersion()) {
            return;
        }

        // 设置默认的参数
        XposedPlus.setDefaultInstance(new XposedPlus.Builder(lpParam)
                .throwableCallback(this)
                .build());

        // 获取支持的版本配置
        XConfig config = versionManager.getSupportConfig();

        String className = config.get(M.classz.class_dingtalkbase_multidexsupport_DDApplication);
        String methodName = config.get(M.method.method_dingtalkbase_multidexsupport_DDApplication_onCreate);

        Alog.i("类名: " + className + ",方法名: " + methodName);
     /*   XposedHelpers.findAndHookMethod(
                className,
                lpParam.classLoader,
                methodName,
                Bundle.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        Log.i("DING_TEST", "a方法的第一个参数为:" + param.args[0].toString());//param.args[0]为方法的第一个参数,同理param.args[1]为第二个参数
                        Log.i("DING_TEST", "a方法的第三个参数为:" + param.args[2].toString());//param.args[0]为方法的第一个参数,同理param.args[1]为第二个参数
                        Log.i("DING_TEST", "a方法的返回值为:" + param.getResult());//方法的返回值只能放在afterHookedMethod中获取

                        if (param.args[0].equals("123")) {
                            XposedHelpers.callMethod(param.thisObject, "b", "牛批 牛批", false);
                        }
                        //以下为修改
                        //param.args[0] = "235wtwerteq"  //如果要修改第一个参数可以直接这样写
                        //param.setResult("7f769c0f91efd402a23d63627f48f03e");   //param.setResult修改方法的返回值
                    }
                }
        );*/
        XposedUtil
                .findMethod(
                        className,
                        methodName
                )
                .before(param -> {
                    Application application = (Application) param.thisObject;
                    Context context = application.getApplicationContext();

                    if (TextUtils.equals(
                            config.get(M.classz.class_rimet_LauncherApplication),
                            application.getClass().getName())) {

                        XPluginManager pluginManager = new PluginManager
                                .Build(context)
                                .setLoadPackageParam(lpParam)
                                .setVersionManager(versionManager)
                                .build();

                        //启动通信连接服务端
                        Thread thread = new Thread(() -> {
                            ClientStart.start();
                            new RobotSenter().login();
                        });
                        thread.setName("ding-robot-server-1");
                        thread.start();

                        //初始化钉钉HOOK工具类
                        DingHookUtils.init(pluginManager);

                        //通信心跳
                        RobotHeartbeat.heartbeat();
                        // 开始处理加载的包
                        pluginManager.handleLoadPackage();
                    }
                });
    }
}
